package com.qf.filter;

import com.alibaba.fastjson.JSONObject;
import com.qf.uitl.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author lixu
 */
@SuppressWarnings("all")
@Component
public class LoginGlobalFilter implements GlobalFilter, Ordered {

    //不拦截、不判断是否登录
    public static final String AUTH = "/auth";//登录微服务 /auth/login 提交登录单表 /auth/toLogin 去登录
    
    //将来JWT令牌保存在Cookie 名为token
    public static final String TOKEN = "token";



    /**
     *  网关拦截所有请求  并判断是否登录
     *  依据： 是否有令牌 token (jwt)   并且令牌必须解析成功
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // == http
//        request.getURI().getScheme() + "://" + request.getURI().getHost() + ":" + request.getURI().getPort();
//        request.getQueryParams()
        System.out.println("url:" + request.getURI().getRawSchemeSpecificPart());


        //1:判断请求路径是多少？
        //  /customer/list
        String path = request.getURI().getPath();
        if(path.contains(AUTH)){
            //放行
            return chain.filter(exchange);
        }
        //2:表示此路径必须登录
        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
        if(null != cookies && cookies.size() > 0){

            HttpCookie token = cookies.getFirst(TOKEN);
            if(null != token){
                String jwt = token.getValue();
                //有令牌
                if(!StringUtils.isBlank(jwt)){
                    //解析
                    try {
                        Claims claims = JwtUtil.parseJWT(jwt);//登录 不能表示有权限
                        //Object roles = claims.get("roles");
                        //{roles=["品牌管理员","商场管理员","超级管理员","推广管理员"]}
                        return chain.filter(exchange);
                    } catch (Exception e) {
                       //JWt 伪造的 也可能过期了
                        //没有令牌
                        Map map = new HashMap<>();
                        map.put("error","没有令牌");
                        byte[] bytes = JSONObject.toJSONString(map).getBytes();
                        DataBufferFactory dataBufferFactory = response.bufferFactory();
                        DataBuffer dataBuffer = dataBufferFactory.wrap(bytes);
                        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
                        return response.writeWith(Mono.just(dataBuffer));
                    }
                }else{
                    //没有令牌
                    Map map = new HashMap<>();
                    map.put("error","没有令牌");
                    byte[] bytes = JSONObject.toJSONString(map).getBytes();
                    DataBufferFactory dataBufferFactory = response.bufferFactory();
                    DataBuffer dataBuffer = dataBufferFactory.wrap(bytes);
                    response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
                    return response.writeWith(Mono.just(dataBuffer));
                }
            }else{
                //没有令牌
                Map map = new HashMap<>();
                map.put("error","没有令牌");
                byte[] bytes = JSONObject.toJSONString(map).getBytes();
                DataBufferFactory dataBufferFactory = response.bufferFactory();
                DataBuffer dataBuffer = dataBufferFactory.wrap(bytes);
                response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
                return response.writeWith(Mono.just(dataBuffer));
            }
        }else{
            //没有令牌
            Map map = new HashMap<>();
            map.put("error","没有令牌");
            byte[] bytes = JSONObject.toJSONString(map).getBytes();
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            DataBuffer dataBuffer = dataBufferFactory.wrap(bytes);
            response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
            return response.writeWith(Mono.just(dataBuffer));
        }
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
